#include "fake_inno_log_cpp.h"
#include <sys/uio.h>
#include <unistd.h>
#include <cstring>
#include <memory>

namespace Fake {
static void std_printf(const std::string& log_msg) {
  iovec iov_entry;
  void* p_void = NULL;
  const void* const p_msg = static_cast<const void* const>(log_msg.c_str());
  std::memcpy(&p_void, &p_msg, sizeof(void*));
  iov_entry.iov_base = p_void;
  iov_entry.iov_len = log_msg.size();

  const std::ptrdiff_t bytes_written = writev(STDOUT_FILENO, &iov_entry, 1);
  if (bytes_written == -1) {
    // Handle write error
  }
}

LogHelper::~LogHelper() noexcept {
  std::ostringstream oss;
  bool should_print{true};
  if (log_lev_ == InnoLogLevel::INNOLOG_LEVEL_DEBUG) {
    oss << "[D] -";
  } else if (log_lev_ == InnoLogLevel::INNOLOG_LEVEL_INFO) {
    oss << "[I] -";
  } else if (log_lev_ == InnoLogLevel::INNOLOG_LEVEL_WARN) {
    oss << "[W] -";
  } else if (log_lev_ == InnoLogLevel::INNOLOG_LEVEL_ERROR) {
    oss << "[E] -";
  } else {
    should_print = false;
  }

  if (should_print) {
    oss << "["<< log_file_ << " - " << log_func_ << ":" << log_lineno_ << "] - ";
    oss << ss_.str() << std::endl;
    std_printf(oss.str());
  }
}

void inno_iov(const std::string &src_file, const std::string &src_func, int32_t src_line, InnoLogLevel src_lev,
              const std::string &log_msg) {
  LogHelper(src_lev, src_file, src_func, src_line) << log_msg;
}

void init_logger() {
}
}  // namespace Fake
